#include <windows.h>

#include "shape_rectangle.h"
#include "drawPrimitivesWindows.h"
#include "list.h"

static HINSTANCE globalInstance;

// initial and end locations of the rectangle
static POINT startPoint, endPoint;

static COLORREF curColor;

// handler for the canvas
static HWND canvasHWND;

static COLORREF WHITE = RGB(255, 255, 255);
static COLORREF BLACK = RGB(0, 0, 0);

static List *shapeList;

static void buttonDown(HWND hWnd, WPARAM wp, LPARAM lp)
{
	startPoint.x = LOWORD(lp);
	startPoint.y = HIWORD(lp);
}

static void buttonUp(HWND hWnd, WPARAM wp, LPARAM lp)
{
	endPoint.x = LOWORD(lp);
	endPoint.y = HIWORD(lp);

	GContextWindows gcw = gContext_createWindowsContext();
	GContext gc = (GContext)gcw;
	ShapeRectangle *sr = rect_new(gc,
			startPoint.x, startPoint.y,
			endPoint.x, endPoint.y);
	Shape *shape = (Shape*)sr;
	list_add(shapeList, shape);

	curColor = BLACK;
	InvalidateRect(hWnd, NULL, TRUE);
}

static void mouseMove(HWND hWnd, WPARAM wp, LPARAM lp)
{
}

static void doPaint(HWND hWnd, PAINTSTRUCT *ps)
{
	if (shapeList)
	{
		ListNode *ln;
		for (ln=list_firstNode(shapeList); ln; ln=ln->next)
		{
			Shape *shape = (Shape*)ln->content;
			gContext_setDC(shape_getContext(shape), ps->hdc);
			shape_draw(shape);
		}
	}

}

static void paint(HWND hWnd, WPARAM wp, LPARAM lp)
{
	if (GetUpdateRect(hWnd, NULL, TRUE))
	{
		PAINTSTRUCT ps;
		BeginPaint(hWnd, &ps);
		doPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
	}
}

static LRESULT CALLBACK
canvasProc(HWND hWnd, UINT message, WPARAM wp, LPARAM lp)
{
	switch(message)
	{
	case WM_CREATE:
		break;
	case WM_SIZE:
		break;
	case WM_PAINT:
		paint(hWnd, wp, lp);
		break;
	case WM_LBUTTONDOWN:
		buttonDown(hWnd, wp, lp);
		break;
	case WM_LBUTTONUP:
		buttonUp(hWnd, wp, lp);
		break;
	case WM_MOUSEMOVE:
		mouseMove(hWnd, wp, lp);
		break;
	default:
		return DefWindowProc(hWnd, message, wp, lp);
	}
	return 0;
}

void canvasResize(int x1, int y1, int x2, int y2)
{
	HDWP hdwp = BeginDeferWindowPos(1);
	DeferWindowPos(hdwp, canvasHWND, NULL, x1, y1, x2, y2,
			SWP_NOZORDER);
	EndDeferWindowPos(hdwp);
}

HWND canvasCreate(HWND parent, int x1, int y1, int x2, int y2)
{
	shapeList = list_new();
	static int registered = 0;
	char *strClass = "canvasClass";
	if (!registered)
	{
		globalInstance = GetModuleHandle(0);
		registered = 1;
		WNDCLASS wc;
		memset(&wc, 0, sizeof(wc));
		wc.style = CS_HREDRAW | CS_VREDRAW;
		wc.lpfnWndProc = canvasProc;
		wc.hInstance = (HANDLE) globalInstance;
		wc.hCursor = LoadCursor(NULL, IDC_ARROW);
		wc.lpszClassName = strClass;
		RegisterClass(&wc);
	}
	canvasHWND =  CreateWindowEx(WS_EX_CLIENTEDGE, strClass, "",
            WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL,
            x1, y1, x2,y2,
            parent, NULL, globalInstance, (LPVOID) 0);
	return canvasHWND;
}
